<template>
  <el-select
    v-model="selectedTags"
    multiple
    filterable
    allow-create
    clearable
    :filter-method="filterTags"
    :remote="isEditable"
    :remote-method="searchTags"
    :default-first-option="true"
    placeholder="输入或选择标签"
    :style="{ width: width }"
    @input="handleInput"
    @change="updateTags"
    @keydown.enter.native="handleEnter"
  >
    <!-- 显示已有的标签 -->
    <el-option v-for="tag in filteredTags" :key="tag.id" :label="tag.label" :value="tag.label">
      <span
        :style="{ backgroundColor: tag.color, color: getTextColor(tag.color) }"
        class="tag-color"
      >
        {{ tag.label }}
      </span>
    </el-option>

    <!-- 如果允许创建标签，且输入不在现有标签中，则显示创建选项 -->
    <el-option
      v-if="isEditable && inputValue && !filteredTags.some((tag) => tag.label === inputValue)"
      :key="inputValue"
      :label="'创建标签：' + inputValue"
      :value="inputValue"
      @click.native="createTag(inputValue)"
    />
  </el-select>
</template>

<script>
import { defineComponent, ref, watch } from 'vue'
import { v4 as uuidv4 } from 'uuid' // 使用uuid库生成唯一ID

export default defineComponent({
  name: 'TagsInput',
  props: {
    tagsSource: {
      type: Array,
      required: true // 下拉数据源 (id, label)
    },
    tagsList: {
      type: Array,
      required: true // 选择的标签列表
    },
    isEditable: {
      type: Boolean,
      default: true // 是否允许创建新标签
    },
    width: {
      type: String,
      default: '300px' // 设置默认宽度
    }
  },
  setup(props, { emit }) {
    const selectedTags = ref([...props.tagsList]) // 当前选中的标签
    const filteredTags = ref([]) // 筛选后的标签
    const inputValue = ref('') // 输入框的当前值

    // 生成随机颜色
    const getRandomLightColor = () => {
      const colors = [
        '#FFC107',
        '#FF9800',
        '#F44336',
        '#E91E63',
        '#9C27B0',
        '#673AB7',
        '#3F51B5',
        '#2196F3',
        '#03A9F4',
        '#00BCD4',
        '#009688',
        '#4CAF50',
        '#8BC34A',
        '#CDDC39',
        '#FFEB3B',
        '#FF5722',
        '#795548',
        '#607D8B'
      ]
      return colors[Math.floor(Math.random() * colors.length)]
    }

    // 根据背景色设置对比色
    const getTextColor = (backgroundColor) => {
      const darkColors = ['#FFC107', '#FFEB3B', '#FF9800', '#FF5722'] // 浅色背景
      return darkColors.includes(backgroundColor) ? '#000' : '#FFF' // 浅色背景时用黑色字体，否则用白色字体
    }

    // 初始化时为每个标签分配随机颜色
    const initializeTags = () => {
      filteredTags.value = props.tagsSource.map((tag) => ({
        ...tag,
        color: tag.color || getRandomLightColor() // 如果没有颜色，分配一个随机颜色
      }))
    }

    // 标签过滤方法，支持下拉搜索
    const filterTags = (query) => {
      if (query) {
        filteredTags.value = props.tagsSource
          .filter((tag) => tag.label.toLowerCase().includes(query.toLowerCase()))
          .map((tag) => ({
            ...tag,
            color: tag.color || getRandomLightColor() // 确保标签有颜色
          }))
      } else {
        initializeTags()
      }
    }

    // 用户输入时的处理函数
    const handleInput = (val) => {
      inputValue.value = val.target ? val.target.value : val // 确保传递的是值而不是事件对象
      filterTags(inputValue.value)
    }

    // 搜索标签时触发的函数（远程搜索）
    const searchTags = (query) => {
      filterTags(query)
    }

    // 创建新标签
    const createTag = (label) => {
      // 检查是否存在相同标签
      if (!props.tagsSource.some((tag) => tag.label === label)) {
        const newTag = {
          id: uuidv4(), // 使用uuid生成唯一ID
          label,
          color: getRandomLightColor(), // 为新标签应用随机颜色
          isNew: true
        }
        emit('update:tagsSource', [...props.tagsSource, newTag]) // 向父组件传递新的标签源
        selectedTags.value.push(newTag.label) // 自动选中新标签
        filteredTags.value.push(newTag) // 确保新标签显示在下拉框中
        updateTags(selectedTags.value)
      }
      inputValue.value = '' // 清空输入框
    }

    // 处理回车键事件
    const handleEnter = () => {
      if (
        isEditable &&
        inputValue.value &&
        !filteredTags.value.some((tag) => tag.label === inputValue.value)
      ) {
        createTag(inputValue.value) // 按下回车创建标签
      }
    }

    // 更新已选标签
    const updateTags = (val) => {
      const selected = props.tagsSource
        .map((tag) => ({ ...tag, isNew: false }))
        .filter((tag) => val.includes(tag.label))

      const newTags = val
        .filter((tagLabel) => !props.tagsSource.some((tag) => tag.label === tagLabel))
        .map((tagLabel) => ({
          id: uuidv4(), // 使用uuid生成唯一ID
          label: tagLabel,
          color: getRandomLightColor(), // 应用随机颜色
          isNew: true
        }))

      emit('update:tagsList', [...selected, ...newTags]) // 向父组件传递更新后的标签列表
    }

    // 监听 props.tagsList 和 props.tagsSource 的变化
    watch(
      () => props.tagsList,
      (newList) => {
        selectedTags.value = newList.map((tag) => tag.label)
      }
    )

    watch(
      () => props.tagsSource,
      (newSource) => {
        initializeTags() // 更新筛选列表时为每个标签分配颜色
      }
    )

    // 初始化标签颜色
    initializeTags()

    return {
      selectedTags,
      filteredTags,
      inputValue,
      handleInput,
      searchTags,
      createTag,
      updateTags,
      handleEnter, // 回车键处理
      getTextColor
    }
  }
})
</script>
<style scoped>
.tag-color {
  padding: 8px; /* 调整标签的内边距 */
  border-radius: 12px; /* 圆角调整 */
  margin: 5px 0; /* 设置上下间隙 */
  display: inline-block;
  min-width: 50px;
  text-align: center;
  line-height: 0.8; /* 设置行高 */
  font-size: 14px; /* 字体大小 */
}
</style>
